/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.geergenbein.parser;

import org.unicode.unihan.parser.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.regex.Pattern;

/**
 *
 * @author Andrew
 */
public class DocumentParser<E> implements Iterator<E>, Iterable<E> {

    private LineNumberReader reader;
    private boolean done;
    private E nextValue = null;
    private LineParser<E> parser;
    private final static Pattern SKIP_LINE_REGEX = Pattern.compile("^\\s*(#.*)?$");
    private final static String ENCODING = "UTF-8";

    public DocumentParser(InputStream is, LineParser<E> lineParser) {
        this.parser = lineParser;
        try {
            reader = new LineNumberReader(new InputStreamReader(is, ENCODING));
        } catch (UnsupportedEncodingException e) {
            // Since the encoding is UTF-8 and we know that UTF-8 is always
            // available in Java, this RuntimeException should never be thrown
            throw new RuntimeException(e);
        }
    }

    public DocumentParser(String path, LineParser<E> lineParser)
            throws FileNotFoundException
    {
        this(new FileInputStream(path), lineParser);
    }

    public Iterator<E> iterator() {
        return this;
    }

    public E next() {
        if (nextValue == null) {
            parseNextLine();
        }
        if (done) {
            throw new NoSuchElementException();
        }
        E t = nextValue;
        nextValue = null;
        return t;
    }

    public boolean hasNext() {
        if (nextValue == null) {
            parseNextLine();
        }
        return !done;
    }

    public void remove() {
        throw new UnsupportedOperationException("Not supported");
    }

    private void parseNextLine() {
        String line;

        try {
            do {
                line = reader.readLine();
            } while (line != null && SKIP_LINE_REGEX.matcher(line).find());
        } catch (IOException e) {
            throw new ParserException("Error accessing reader", e);
        }

        if (line == null) {
            done = true;
        } else {
            nextValue = parser.parse(line);
        }
    }

}
